package services

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

// SiliconFlowService SiliconFlow API 服务
type SiliconFlowService struct {
	apiKey string
	baseURL string
}

// NewSiliconFlowService 创建 SiliconFlow 服务
func NewSiliconFlowService() *SiliconFlowService {
	return &SiliconFlowService{
		apiKey:  "",
		baseURL: "https://api.siliconflow.cn/v1",
	}
}

// ModelInfo 模型信息
type ModelInfo struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

var defaultModels = []ModelInfo{
	{ID: "Qwen/Qwen3-VL-8B-Instruct", Name: "Qwen3-VL-8B-Instruct (OCR)"},
	{ID: "qwen/qwen-vl-max", Name: "Qwen-VL-Max (OCR)"},
	{ID: "qwen/qwen-vl-plus", Name: "Qwen-VL-Plus (OCR)"},
	{ID: "qwen/qwen-vl", Name: "Qwen-VL (OCR)"},
}

// SetAPIKey 设置 API Key
func (s *SiliconFlowService) SetAPIKey(apiKey string) {
	s.apiKey = apiKey
}

// GetModels 获取可用的 OCR 模型列表
func (s *SiliconFlowService) GetModels() ([]ModelInfo, error) {
	if s.apiKey == "" {
		return defaultModels, nil
	}

	// 调用 SiliconFlow API 获取模型列表
	// 根据官方文档：GET /v1/models
	// 不限制 type 参数，获取所有模型，然后筛选出支持图片的模型
	url := fmt.Sprintf("%s/models", s.baseURL)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+s.apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 30 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API 调用失败: %s", string(body))
	}

	// 解析响应，根据官方文档，响应格式为：
	// {
	//   "object": "list",
	//   "data": [
	//     {
	//       "id": "model-id",
	//       "object": "model",
	//       "created": 0,
	//       "owned_by": ""
	//     }
	//   ]
	// }
	var modelsResp struct {
		Object string `json:"object"`
		Data   []struct {
			ID      string `json:"id"`
			Object  string `json:"object"`
			Created int64  `json:"created"`
			OwnedBy string `json:"owned_by"`
		} `json:"data"`
	}
	
	err = json.Unmarshal(body, &modelsResp)
	if err != nil {
		return nil, fmt.Errorf("解析响应失败: %v, 响应内容: %s", err, string(body))
	}

	// 筛选支持图片的模型
	keywords := []string{"vlm", "ocr", "vision", "visual", "qwen-vl", "qwen3-vl", "vl-", "-vl", "multimodal", "image", "gpt-4-vision", "gpt4-vision", "claude-vision", "gemini-vision"}
	var ocrModels []ModelInfo
	seen := make(map[string]bool)
	
	for _, model := range modelsResp.Data {
		idLower := strings.ToLower(model.ID)
		for _, kw := range keywords {
			if strings.Contains(idLower, kw) && !seen[model.ID] {
				ocrModels = append(ocrModels, ModelInfo{ID: model.ID, Name: model.ID})
				seen[model.ID] = true
				break
			}
		}
	}

	if len(ocrModels) == 0 {
		return defaultModels, nil
	}
	return ocrModels, nil
}

// RecognizeImageStream 使用 SiliconFlow API 流式识别图片
// onChunk 回调函数会在每次收到数据块时被调用
func (s *SiliconFlowService) RecognizeImageStream(modelID string, imageBase64 string, onChunk func(string)) error {
	if s.apiKey == "" {
		return fmt.Errorf("请先设置 API Key")
	}

	// 如果未指定模型，使用默认模型
	if modelID == "" {
		modelID = "Qwen/Qwen3-VL-8B-Instruct"
	}

	url := fmt.Sprintf("%s/chat/completions", s.baseURL)
	requestBody := map[string]interface{}{
		"model":            modelID,
		"stream":           true,
		"max_tokens":       8000,
		"temperature":      0.1,
		"top_p":            0.7,
		"top_k":            50,
		"frequency_penalty": 0.5,
		"response_format":  map[string]string{"type": "text"},
		"messages": []map[string]interface{}{
			{
				"role": "user",
				"content": []map[string]interface{}{
					{"type": "text", "text": "识别文本"},
					{"type": "image_url", "image_url": map[string]string{
						"url":    "data:image/jpeg;base64," + imageBase64,
						"detail": "auto",
					}},
				},
			},
		},
	}

	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonData)))
	if err != nil {
		return err
	}

	req.Header.Set("Authorization", "Bearer "+s.apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 120 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		var errorResp map[string]interface{}
		if err := json.Unmarshal(body, &errorResp); err == nil {
			if msg, ok := errorResp["message"].(string); ok {
				return fmt.Errorf("API 调用失败: %s", msg)
			}
		}
		return fmt.Errorf("API 调用失败 (状态码: %d): %s", resp.StatusCode, string(body))
	}

	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		line := scanner.Text()
		if line == "" || !strings.HasPrefix(line, "data: ") {
			continue
		}
		
		dataStr := strings.TrimPrefix(line, "data: ")
		if dataStr == "[DONE]" {
			break
		}
		
		var chunk map[string]interface{}
		if json.Unmarshal([]byte(dataStr), &chunk) != nil {
			continue
		}
		
		choices, _ := chunk["choices"].([]interface{})
		if len(choices) == 0 {
			continue
		}
		
		choice, _ := choices[0].(map[string]interface{})
		delta, _ := choice["delta"].(map[string]interface{})
		if content, ok := delta["content"].(string); ok && content != "" {
			if onChunk != nil {
				onChunk(content)
			}
		}
	}
	return scanner.Err()
}

// RecognizeImage 使用 SiliconFlow API 识别图片（非流式，用于批量处理）
func (s *SiliconFlowService) RecognizeImage(modelID string, imageBase64 string) (string, error) {
	if s.apiKey == "" {
		return "", fmt.Errorf("请先设置 API Key")
	}

	// 如果未指定模型，使用默认模型
	if modelID == "" {
		modelID = "Qwen/Qwen3-VL-8B-Instruct"
	}

	url := fmt.Sprintf("%s/chat/completions", s.baseURL)
	requestBody := map[string]interface{}{
		"model":            modelID,
		"stream":           false,
		"max_tokens":       8000,
		"temperature":      0.1,
		"top_p":            0.7,
		"top_k":            50,
		"frequency_penalty": 0.5,
		"response_format":  map[string]string{"type": "text"},
		"messages": []map[string]interface{}{
			{
				"role": "user",
				"content": []map[string]interface{}{
					{"type": "text", "text": "识别文本，提取所有关键信息，以JSON格式返回，包含字段名和对应的值"},
					{"type": "image_url", "image_url": map[string]string{
						"url":    "data:image/jpeg;base64," + imageBase64,
						"detail": "auto",
					}},
				},
			},
		},
	}

	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		return "", err
	}

	req, err := http.NewRequest("POST", url, strings.NewReader(string(jsonData)))
	if err != nil {
		return "", err
	}

	req.Header.Set("Authorization", "Bearer "+s.apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{Timeout: 120 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		var errorResp map[string]interface{}
		if err := json.Unmarshal(body, &errorResp); err == nil {
			if msg, ok := errorResp["message"].(string); ok {
				return "", fmt.Errorf("API 调用失败: %s", msg)
			}
		}
		return "", fmt.Errorf("API 调用失败 (状态码: %d): %s", resp.StatusCode, string(body))
	}

	var response map[string]interface{}
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	err = json.Unmarshal(body, &response)
	if err != nil {
		return "", err
	}

	choices, _ := response["choices"].([]interface{})
	if len(choices) == 0 {
		return "", fmt.Errorf("API 返回空结果")
	}

	choice, _ := choices[0].(map[string]interface{})
	message, _ := choice["message"].(map[string]interface{})
	content, _ := message["content"].(string)

	return content, nil
}
